Scripting Tips



I started scripting in the year 2001 with absolutely no programming experience. Now with three years of experience in programming in mIRC script, a couple in JavaScript, six months or so in c, c++, perl, Java and two months in ActionScript I have gotten and read (it includes The Practice of Programming - Kernighan and Pike) many tips on programming, which has made me a better programmer in general today. Eventually I invented some of my own. Here I share my tips with you specifically related to mIRC scripting and a few in general programming. Hope you find them helpful.

1). The mIRC Help File is where you can find almost everything you want to know about scripting. If there's something confusing or intriguing you, open the Help File (press F1 in mIRC), click on the Index tab and search there. Note: If you are referring a command, when searching the Index, prefix the command name with a front slash(/). A quicker way to search for something in the Help File is by using the /help command. It takes one parameter - the subject you want to look up. Eg: /help /set. Another example: /help $didtok. If you can, print out the Help File. If not the whole, atleast the parts you want to read about. I still have the printout of the whole mIRC v5.91 Help File.

2). Despite the Help File you may sometimes really need to ask someone more experienced to help you out with something. I must say sometimes the mIRC Help File can be a little incomplete and confusing for a total newbie. In these case you can get help from experienced scripters on various channels on various IRC Networks. But make sure you have tried your best to find it out by yourself from the Help File first or you could get rude responses. And also be aware of the channel policies before you ask your questions. I am sure you can find help on #mirc, #help, #helpdesk, #scripters and #scripting on DALnet, Undernet and EFnet. The #scripters and #helpdesk channels on DALnet are where I got most of my help from.

I take this opportunity to thank Wiggle, watot, pendulum, Mackavelli, probably and others for all the help they gave me when I started out. And there was one guy who patiently helped me with sockets (three hours). I forgot his nick, thanks to him too. You may sometimes find me on #scripters and #helpdesk on DALnet. I don't use any particular nick. But I always try my best to help people who are starting out.

3). Most of the beginners use the front slash (/) to prefix the commands in their scripts. You don't really need to that. I wrote a ChatBot composed of three huge INI files when I started out. And all the commands were prefixed with the front slashes! =:D

Instead of:
alias test {
    /echo -a Hello!
    /echo -a Today is $day $+ .
}


You can write:
alias test {
    echo -a Hello!
    echo -a Today is $day $+ .
}


4). Don't overuse pipes (|). They make your code look dirty and hard to debug. Try to keep one statement in a line. What happens when you get an error message "* Too many parameters: $gettok (line 128, cool.mrc)" and you have 10 pipes all doing a $gettok in line 128? I'd suggest you to use curly brackets whenever there's going to be more than one statements in a code.

Instead of:
alias test { echo -a Hello! | echo -a $date | msg # Hey today is $date | echo -a DONE! }

Use:
alias test {
    echo -a Hello!
    echo -a $date
    msg # Hey today is $date
    echo -a DONE!
}


5). Use while instead of combining if and goto to loop.

Instead of:

alias show {
  var %nicks 
  var %i 0 
  :loop 
  inc %i 
  if (%i <= $nick(#,0)) { 
    %nicks = $addtok(%nicks,$nick(#,%i),32) 
    goto loop 
  } 
  echo -a The nicks on # are: %nicks 
}
Use this instead:
alias show {
  var %nicks 
  var %i 1 
  while (%i <= $nick(#,0)) { 
    %nicks = $addtok(%nicks,$nick(#,%i),32) 
    inc %i 
  } 
  echo -a The nicks on # are: %nicks 
}
I am not saying goto isn't of any good use. It has it's own place. But when it comes to looping using while is advisable.

6). If you need to perform a set of commands frequently or from different parts of your script, create a local alias and call it instead of writing the codes for all the places. The example below is just a silly one, you will find the use more useful in more complex scripts.

Instead of:
on *:text:*:?: {
    msg $nick I am very busy. This is line number 1.
    msg $nick Line no. 2!
    msg $nick Here goes line no. 3.
    msg $nick Message me when I am free.
}

on *:notice:*:?: {
    msg $nick I am very busy. This is line number 1.
    msg $nick Line no. 2!
    msg $nick Here goes line no. 3.
    msg $nick Message me when I am free.
}


Do it this way:
alias -l myMsg {
    msg $nick I am very busy. This is line number 1.
    msg $nick Line no. 2!
    msg $nick Here goes line no. 3.
    msg $nick Message me when I am free.
}

on *:text:*:?: myMsg
on *:notice:*:?: myMsg


7). I personally prefer to save my mIRC scripts files with the .mrc extension. You don't get the ini lines like those saved with the .ini extension. Besides .mrc is mIRC's own extension. Using .mrc doesn't compromise your script in any way. You can use write instead of writeini.

8). Use $scriptdir instead of $mircdir. You have no guarantee that the user will place your script in the mIRC directory. In some situations even using $scriptdir will give you an error. Especially when loading files from a directory with spaces or using a DLL, in these cases you can use the $shortfn() identifier. Eg: $shortfn($scriptdirsystem\settings.ini). In case you should specify a file or directory with spaces directly, enclose them with double quotes. Eg: load -rs "Cool Scripts\cool.mrc". Note: Your script will work fine on Windows XP even if you don't use $shortfn() for pathnames with spaces. But it gives an error on Window 98. Always use $shortfn() to make your scripts OS compatible.

I discovered recently write won't write a file in a directory with spaces even if you used $shortfn($scripdirMYFILE.TXT). To overcome this problem use write $shortfn($scriptdir) $+ MYFILE.TXT blah blah blah.

9). When you assign a global variable prefix them with a unique name. Preferably the name of your script. Eg: %myScipt.value1, %myScript.value2, %myScript.value3 etc. There are two good reasons why you should do that. First, there won't be any clashes in variable names. If you set a variable called %nicks, there could be other scripts which creates and uses the same variable name. Second, unsetting them is much easier. You can unset all your variables with unset myScript.*. Don't forget to unset the variables set by your script when it is unloaded. And never use the unsetall command from your script. Prefixing values and names with the name of your script applies to other things like dialog boxes, custom windows, aliases, timers, hash tables, #groups, sockets etc. too.

10). Don't use $isin to detect strings. Use $istok() instead. I have seen many bots kicking and banning people for saying innocuous things like "I am late for my class", "Charles Dickens is my favorite author" and stuff.

Instead of:
on *:text:*:#: {
  if ((ass isin $1-) || (dick isin $1-)) {
    ban $Chan $nick
    kick $chan $nick Don't swear here!
  }
}
Use:
on *:text:*:#: {
  if (($istok($1-,ass,32) == $true) || ($istok($1-,dick,32) == $true)) {
    ban $chan $nick
    kick $chan $nick Don't swear here!
  }
}
11). To suppress the display of executed commands like
 -> *Bat_man* Where are you?
* Loaded aliases 'C:\mIRC v6.03\aliases.ini'
* Timer buzzer activated" 
prefix the command with a dot (.). Eg:

.msg Bat_man where are you?
.load -a aliases.ini
.timerbuzzer 1 3 echo -a BUZZ!


12). If you create a dialog-based script, create a popup for the dialog instead of letting the user type some commands in the command line. It's more convenient for the user and not difficult a job for you - just create a menu in the dialog script itself. And also when creating the popup for the dialog make sure it first checks if the dialog is open and just doesn't try to open it otherwise you get an error "* /dialog: 'myDialog' name in use". The code for creating the popup and checking is given below.

menu channel,menubar,nicklist,status {
  My Dialog: {
    if ($dialog(myDialog)) dialog -v myDialog myDialog
    else dialog -md myDialog myDialog 
  }
} 
13). When using icons (images) in your dialog box make sure you let the user choose from a list of images which blends best with the system gray color. They look different on different system depending on many factors. And can range from beigish gray to bluish gray (according to what I have encountered so far). If you don't use the proper color, the images stand out. And they certainly don't look very good. I wrote a small dialog-based script, Spyder DIS, to help the user choose the proper image for Spyder GuitarChords. It will be available for download once I make it customizable for any script.

14). Use PNG graphics for your scripts, they are small in size, looks almost as good as JPG or BMP. BMP images are too huge, JPG images are large and GIF is not supported by dialogs. So the best option is to use PNG for your scripts especially dialogs.

15). If you write a popup or a dialog box script. Make sure they display only the available options. Eg: Enable or display the options available to an OP only if the user is an OP. Put some logic into your popups or dialog boxes. Another example: If you write a portscanner the "Start" button should be disabled once it's clicked and the scanning process is going on.

16). When it comes to variables and aliases for your scripts try to make them local if not absolutely necessary. Local variables are faster and you don't need to unset them. The reason behind using local aliases is it might conflict with other scripts which created and uses the same alias name. Also use meaningful variable and alias names. %opnick makes more sense than %o and the alias countNicks is more preferable to cn for reasons of clarity, logic and ease in debugging.

17). Remember there can be only one specific event definition for an event in a remote file. If there are two, only the first one will be valid. This is one common reason why newbies find their script is not working. See the example below, the whole thing is in one script file:

on *:text:*:?: msg $nick Hi there!
on *:text:Hi:?: msg $nick Hello!


The creator of this script will complain about "on *:text:Hi:?: msg $nick Hello!" being not working. It's obvious it won't work. It will work if it were in a separate file though. As I said the event definition should be specific. (The wildcard means "anything", it nullify all specificities). Look at the example below. Both the event definitions use ON TEXT but they are not the same. So this script works fine.

on *:text:Hello:?: msg $nick You said Hello.
on *:text:Hi:?: msg $nick You said Hi.


18). Sometimes you may wonder why an apparently correct expression is not working as expected, especially if it involves some variables or identifier. Chances are, some character involved in the expression is messing things up. For example $calc($1+$2) won't work as expected. It will return only the first parameter instead of the sum of $1 and $2. mIRC scrip interpreter has been confused by the immediate + sign following the literal $1. It knows $1-, but what is $1+? So don't forget to give the operands and the operator their 'personal spaces' when it involves identifiers. Do it this way $calc($1 + $2). Though you don't need to put spaces between the operands in calculations involving constant numerics like $calc(2+3) etc.

In calculations involving the modulo operator, always include a space after the '%' or the mIRC script interpreter will think the second operand is a variable and mess things up. $calc(10%2) will return '10' which's a very incorrect result. It's all because of the absence of space between the operands. The right way is $calc(10 % 2) or $calc(10% 2).

In some situations variables and identifiers need to be given not just 'personal spaces' but also a special enclosement within square brackets [ ]. Otherwise their values won't be evaluated at all! Set a variable %t with the value "Hi there!". Now type //echo -a % $+ t. What you get is '%t', not the value of the variable %t. The expression demands special evaluation. Now type //echo -a % [ $+ $1 ]. There you are! In any expression involving either a variable or an identifier, if things don't work as expected, evaluation brackets may be what you need to fix it.

19). Always include an ON LOAD and ON UNLOAD event definition for your script. When the user loads the scripts you might like to check if the mIRC version is compatible with your script or not and perform some action accordingly. It's also a good practice to inform the user that the script file has been loaded successfully and intruct him/her what to do next. When the user unloads your script it's good manners to unset all the globals variables your script had set and then inform the user that the file has been successfully unloaded.
20). If your project is a huge and complex one, divide it into multiple files and concentrate on a particular aspect of the program in one file. Use script customised global aliases to call them from other files. This way you won't end up working on a 2000 lines file scrolling up and down and up and down editing and debugging various sections of the program. When everything is ready, you can copy the contents of all the component files in one file to get the final script file or load the component files from the main file. This way editing, programming and debugging is a whole lot easier.

21). Comment your scripts. Especially if it's a long one and you plan to write future versions. When you are writing the script, everything may be clear to you but when you look at the codes again after a six months break they won't be as clear as it used to be. Be warned it can be as early as a week. Your comments shouldn't state self-evident information, such as that fact that set %n 1 has set the value 1 for %n. Instead it should informing things which are not immediately evident from the code and tell what that intention of the code is looking from a human mindset. The components that need commenting without failure are aliases, variable setting and decision making structures, especially in scripts that run hundreds of lines.

22). Make your script flexible, configurable and give maximum sensible customizablity to the user. Don't hard code constants into your scripts. Instead use variables which can be modified by the user with the use of some command or click. This point has got a very wide area of application. Check your script for restriction of any desirable personal preference in any part of the code and fix it. For instance, instead of timer 1 5 echo -a TIME UP! how about timer 1 %myTime echo -a TIME UP! %myTime seconds.? Something along this line. Got it?

One small example which deals with flexibility:
echo -a 2Hola Mundo! will echo "Hola Mundo!" in the active window in dark blue text (notice the 2 after ). Now what happens if the script is run in mIRC with black/dark brown/drak blue bgcolor setting? It would be invisible or hard to read. Instead you can use echo $color(info) -a Hola Mundo! to adjust the text color according to the user's color setting and combination.

Extra Info: I am working on a new project SpyderX. It will generalize all the commandline based scripts and do lots more. All I can say about SpyderX now is that it's going to change the way commandline based scripts work. Watch and wait.

23). Make sure to include efficient error handling in your scripts. They tend to bloat up the code, I know. But if you are really interested in sharing your scripts with others, why not make using your scripts a pleasant experience for them? Tip no. 12 contains a good example on error handlihg. Honestly, seeing an error message is very disappointing. Besides, the elegancy of your programming style will be reflected in the way your script handle errors. It's one thing to get a result and quite another to do it with impeccable style.

24). Study the codes written by other scripters. Learn from their scripting style. If you are out to learn scripting all on your own it's going to take you a long time if not forever. And you are very likely to miss some of the things which are not documented in the Help File and mentioned in the various tutorials available on the net. Download some scripts written by good scripters, dissect and study them. And hey, no ripping. Instead write your own impressive scripts.

These 24 tips are all I can think of as I update the file. I may add more points later on, check again for udates.

END OF FILE:


Hage Yaapa
Update: 22nd June 2004
http://spyderwares.com



Copyright © 2002-2004 SpyderWares.
http://spyderwares.com